#include <iostream> // 标准输入输出
#include <vector>   // 动态数组
#include <algorithm> // min, sort, abs等算法
#include <map>      // 映射 (坐标 -> 索引)
#include <set>      // 集合 (存储唯一坐标)

// INF: 一个足够大的数表示无穷大，用于成本计算
const long long INF = 4e18; 

// 辅助结构体: 存储值和对应索引，用于DP计算和路径重构时的选择
struct ValueWithIndex {
    long long value; // 值 (例如: dp_prev[k] +/- C*coords[k])
    int index;       // 该值对应的在'coords'数组中的原始索引 k

    ValueWithIndex(long long v = INF, int idx = -1) : value(v), index(idx) {}

    // 比较函数: 值优先，值相同时索引小的优先 (确保确定性)
    bool operator<(const ValueWithIndex& other) const {
        if (value != other.value) {
            return value < other.value;
        }
        return index < other.index; 
    }
};

int main() {
    std::ios_base::sync_with_stdio(false); // 关闭同步，加速I/O
    std::cin.tie(NULL); // 解除cin与cout的绑定

    int n_items; // 物品数量N
    long long c_cost_self; // 自己移动成本C
    long long d_cost_merchant; // 商人移动成本D
    std::cin >> n_items >> c_cost_self >> d_cost_merchant;

    std::vector<long long> merchant_initial_x(n_items); // 商人初始位置X_i
    std::set<long long> unique_coords_set; // 存储所有唯一坐标 (包括0和所有X_i)
    unique_coords_set.insert(0); // 加入自己的初始位置0
    for (int i = 0; i < n_items; ++i) {
        std::cin >> merchant_initial_x[i];
        unique_coords_set.insert(merchant_initial_x[i]);
    }

    // `coords`: 排序后的唯一坐标列表
    std::vector<long long> coords(unique_coords_set.begin(), unique_coords_set.end());
    int m_coords = coords.size(); // 唯一坐标的数量
    std::map<long long, int> coord_to_idx_map; // 坐标值 -> `coords`数组索引的映射
    for (int i = 0; i < m_coords; ++i) {
        coord_to_idx_map[coords[i]] = i;
    }

    // DP状态 (空间优化): dp_prev存上一个物品的最小成本, dp_curr存当前物品
    std::vector<long long> dp_prev(m_coords, INF);
    std::vector<long long> dp_curr(m_coords); 

    // parent_coord_idx_all_steps[i][j]: 收集第i物品于coords[j]时, 第i-1物品的收集点索引
    std::vector<std::vector<int>> parent_coord_idx_all_steps(n_items + 1, std::vector<int>(m_coords, -1));

    // DP基准情况: 收集第0个物品(概念上的)后，在坐标0，成本0
    if (coord_to_idx_map.count(0)) { // 坐标0一定存在于map中
        dp_prev[coord_to_idx_map[0]] = 0;
    }

    // 动态规划: 遍历每个物品 i (从1到N)
    for (int i = 1; i <= n_items; ++i) {
        std::fill(dp_curr.begin(), dp_curr.end(), INF); // 初始化当前物品的DP值为INF
        long long current_item_merchant_x = merchant_initial_x[i-1]; // 当前商人位置 (0-indexed)

        // 预计算 val1_terms 和 val2_terms 用于优化“我们移动”的成本计算
        std::vector<ValueWithIndex> val1_terms(m_coords), val2_terms(m_coords);
        for (int k = 0; k < m_coords; ++k) {
            if (dp_prev[k] == INF) { // 如果上一个状态不可达
                val1_terms[k] = ValueWithIndex(INF, k);
                val2_terms[k] = ValueWithIndex(INF, k);
            } else {
                val1_terms[k] = ValueWithIndex(dp_prev[k] - c_cost_self * coords[k], k);
                val2_terms[k] = ValueWithIndex(dp_prev[k] + c_cost_self * coords[k], k);
            }
        }
        
        // min_pref_val1[j] = min_{k <= j} (dp_prev[k] - C*coords[k]) (前缀最小值)
        std::vector<ValueWithIndex> min_pref_val1(m_coords);
        if (m_coords > 0) { // 确保coords非空
            min_pref_val1[0] = val1_terms[0];
            for (int k = 1; k < m_coords; ++k) {
                min_pref_val1[k] = std::min(min_pref_val1[k-1], val1_terms[k]);
            }
        }

        // min_suff_val2[j] = min_{k >= j} (dp_prev[k] + C*coords[k]) (后缀最小值)
        std::vector<ValueWithIndex> min_suff_val2(m_coords);
        if (m_coords > 0) { // 确保coords非空
            min_suff_val2[m_coords-1] = val2_terms[m_coords-1];
            for (int k = m_coords - 2; k >= 0; --k) {
                min_suff_val2[k] = std::min(min_suff_val2[k+1], val2_terms[k]);
            }
        }
        
        // 遍历所有可能的当前物品收集点 coords[j]
        for (int j = 0; j < m_coords; ++j) {
            // 商人移动成本: 商人i从其初始位置移到coords[j]
            long long cost_merchant_move = d_cost_merchant * std::abs(current_item_merchant_x - coords[j]);
            
            long long min_total_us_move_cost = INF; // 我们自己移动的最小成本
            int best_prev_k_idx = -1; // 达到此最小成本时，上一个物品的收集点索引

            // 选择1: 上个物品在 k' <= j 处收集, 我们移向 j. 成本: C*coords[j] + min_pref_val1[j].value
            ValueWithIndex choice1(INF, -1);
            if (m_coords > 0 && min_pref_val1[j].value != INF) { // 检查可达性
                choice1.value = c_cost_self * coords[j] + min_pref_val1[j].value;
                choice1.index = min_pref_val1[j].index; // 记录来源索引 k
            }

            // 选择2: 上个物品在 k' >= j 处收集, 我们移向 j. 成本: -C*coords[j] + min_suff_val2[j].value
            ValueWithIndex choice2(INF, -1);
            if (m_coords > 0 && min_suff_val2[j].value != INF) { // 检查可达性
                 choice2.value = -c_cost_self * coords[j] + min_suff_val2[j].value;
                 choice2.index = min_suff_val2[j].index; // 记录来源索引 k
            }
            
            // 比较选择1和选择2，ValueWithIndex的比较运算符处理了成本相同的情况
            if (choice1 < choice2) {
                min_total_us_move_cost = choice1.value;
                best_prev_k_idx = choice1.index;
            } else {
                min_total_us_move_cost = choice2.value;
                best_prev_k_idx = choice2.index;
            }
            
            if (min_total_us_move_cost == INF) { // 如果无法从任何先前状态到达coords[j]
                dp_curr[j] = INF;
            } else {
                // 检查加法溢出
                if (cost_merchant_move >= INF - min_total_us_move_cost) { 
                     dp_curr[j] = INF;
                } else {
                    dp_curr[j] = min_total_us_move_cost + cost_merchant_move; // 总成本
                    parent_coord_idx_all_steps[i][j] = best_prev_k_idx; // 记录父状态索引
                }
            }
        }
        dp_prev = dp_curr; // 当前DP状态成为下一次迭代的“前一个”状态
    }

    // 寻找收集完所有N个物品后的最小总成本
    long long min_total_final_cost = INF;
    int final_item_coord_idx = -1; // 第N个物品的收集点索引

    for (int j = 0; j < m_coords; ++j) {
        if (dp_prev[j] < min_total_final_cost) { // dp_prev此时存的是收集完N个物品的成本
            min_total_final_cost = dp_prev[j];
            final_item_coord_idx = j;
        } else if (dp_prev[j] == min_total_final_cost) {
            // 成本相同时，选择坐标索引j较小的 (因为coords已排序，即实际坐标值较小)
            if (final_item_coord_idx == -1 || j < final_item_coord_idx) {
                 final_item_coord_idx = j;
            }
        }
    }
    std::cout << min_total_final_cost << std::endl;

    // 重构路径: 从最后一个物品的收集点回溯
    std::vector<long long> result_path_coords(n_items); // 存储每个物品的收集坐标A_i
    int current_k_idx_in_coords = final_item_coord_idx; // 从第N个物品的收集点开始
    
    for (int i = n_items; i >= 1; --i) { // 从物品N回溯到物品1
        // 题目保证有解，所以 current_k_idx_in_coords 总是有效的
        result_path_coords[i-1] = coords[current_k_idx_in_coords]; // 记录物品i的收集坐标
        // 找到物品i-1的收集点索引
        current_k_idx_in_coords = parent_coord_idx_all_steps[i][current_k_idx_in_coords];
    }

    // 输出路径
    for (int i = 0; i < n_items; ++i) {
        std::cout << result_path_coords[i] << (i == n_items - 1 ? "" : " ");
    }
    std::cout << std::endl;

    return 0;
}